<?php
/**
 * Created by PhpStorm.
 * User: maqun
 * Date: 2016/2/29
 * Time: 12:35
 * 问题导入
 */
class ImportAction extends BaseAction{

    protected $language_name = array();

    public function _initialize(){
        self::$action = 2;
        parent::_initialize();
        $this->language_name = C('OJ_LAN_NAME');
    }

    #问题导入页面显示
    public function importPage(){

        $maxfile = min(ini_get("upload_max_filesize"), ini_get("post_max_size"));
        $OJ_DATA = C('OJ_DATA');

        $show_form = true;
        $is_w_ojdata = true;
        if (!$this->writable($OJ_DATA)) {
            $is_w_ojdata = false;
            $show_form=false;
        }
        $is_w_uoload = true;
        if (!$this->writable("../upload")) {
            $is_w_uoload = false;
            $show_form   =false;
        }

        $this->assign('is_w_ojdata', $is_w_ojdata);
        $this->assign('is_w_uoload', $is_w_uoload);
        $this->assign('show_form', $show_form);
        $this->assign('maxfile', $maxfile);

        $this->display('import');
    }

    #问题导入提交
    public function import(){

        $model   = D('Problem');
        $OJ_DATA = C('OJ_DATA');

        if ($_FILES ["fps"] ["error"] > 0) {
            echo "Error: " . $_FILES ["fps"] ["error"] . "File size is too big, change in PHP.ini<br />";
        } else {

            $tempfile = $_FILES ["fps"] ["tmp_name"];
            $xmlDoc=simplexml_load_file($tempfile);

            $searchNodes = $xmlDoc->xpath ( "/fps/item" );

            foreach($searchNodes as $searchNode) {

                $data = array();
                $data['title']      = $searchNode->title;
                $data['time_limit'] = $searchNode->time_limit;

                $unit               = $this->getAttribute($searchNode,'time_limit','unit');
                if($unit == 'ms' ){
                    $data['time_limit'] /= 1000;
                }

                $data['memory_limit'] = $this->getValue ( $searchNode, 'memory_limit' );
                $unit                 = $this->getAttribute($searchNode,'memory_limit','unit');
                if($unit=='kb'){
                    $data['memory_limit'] /= 1024;
                }

                $data['description']  = $this->getValue ( $searchNode, 'description' );
                $data['input']        = $this->getValue ( $searchNode, 'input' );
                $data['output']       = $this->getValue ( $searchNode, 'output' );
                $data['sample_input'] = $this->getValue ( $searchNode, 'sample_input' );
                $data['sample_output']= $this->getValue ( $searchNode, 'sample_output' );

                $data['hint']         = $this->getValue ( $searchNode, 'hint' );
                $data['source']       = $this->getValue ( $searchNode, 'source' );

                $data['solutions']    = $searchNode->children()->solution;
                $data['spjcode']      = $this->getValue ( $searchNode, 'spj' );
                $data['spj']          = trim($data['spjcode']) ? 1 : 0;

                $data['difficulty']   = $this->getValue ( $searchNode, 'difficulty' );
                //将xmlSimple返回的对象强制类型转换成字符串
                $data = array_map(function($val){
                    return (string)$val;
                },$data);

                if(!$model->hasProblem($data['title'])){

                    $pid = $model->addProblem ($data);

                    if($spid == 0){
                        $spid   =   $pid;
                    }

                    $basedir = "$OJ_DATA/$pid";
                    mkdir ( $basedir );
                    if(strlen($data['sample_input'])){
                        $this->mkdata($pid,"sample.in",$data['sample_input'],$OJ_DATA);
                    }

                    if(strlen($data['$sample_output'])){
                        $this->mkdata($pid,"sample.out",$data['$sample_output'],$OJ_DATA);
                    }

                    $testinputs   =  $searchNode->children()->test_input;
                    $testno       =  0;

                    foreach($testinputs as $testNode){
                        $this->mkdata($pid,"test".$testno++.".in",$testNode,$OJ_DATA);
                    }

                    $testinputs   =$searchNode->children()->test_output;
                    $testno       =0;
                    foreach($testinputs as $testNode){

                       $this->mkdata($pid,"test".$testno++.".out",$testNode,$OJ_DATA);
                    }

                    $images       = ($searchNode->children()->img);
                    $did          = array();
                    $testno       = 0;
                    foreach($images as $img){

                        $src=$this->getValue($img,"src");
                        if(!in_array($src,$did)){
                            $base64     =   $this->getValue($img,"base64");
                            $ext        =   pathinfo($src);
                            $ext        =   strtolower($ext['extension']);

                            if(!stristr(",jpeg,jpg,png,gif,bmp",$ext)){
                                $ext="bad";
                                exit(1);
                            }

                            $testno++;
                            $newpath="../upload/pimg".$pid."_".$testno.".".$ext;

                            $this->image_save_file($newpath,$base64);
                            $newpath   =   dirname($_SERVER['REQUEST_URI'] )."/../upload/pimg".$pid."_".$testno.".".$ext;

                            $up_data['description'] = "replace(description,'$src','$newpath')";
                            $up_data['input']       = "replace(input,'$src','$newpath')";
                            $up_data['output']      = "replace(output,'$src','$newpath')";
                            $up_data['hint']        = "replace(hint,'$src','$newpath')";

                            $model->where("problem_id=$pid")->save($up_data);

                            array_push($did,$src);
                        }

                    }

                    foreach($data['solutions'] as $solution) {

                        $language =$solution->attributes()->language;

                        D('Solution')->submitSolution($pid,$solution,$language);
                    }
                }else{
                    $this->error($data['title']."is already in this OJ");
                    exit;
                }

            }
            unlink ( $tempfile );
            if($spid>0){
                $this->success('导入成功',U('/Problem/index/'));
                exit;
//                require_once("../include/set_get_key.php");
//                echo "<br><a class=blue href=contest_add.php?spid=$spid&getkey=".$_SESSION['getkey'].">Use these problems to create a contest.</a>";
            }
        }
        $this->error('error');
        exit;
    }
    #判断目录是否可写
    public function writable($path){
        $ret=false;
        $fp=fopen($path."/testifwritable.tst","w");
        $ret=!($fp===false);
        fclose($fp);
        unlink($path."/testifwritable.tst");
        return $ret;
    }

    public function getAttribute($Node, $TagName,$attribute) {
        return (string)$Node->children()->$TagName->attributes()->$attribute;
    }

    public function getValue($Node, $TagName) {

        return (string)$Node->$TagName;
    }

    public function mkdata($pid,$filename,$input,$OJ_DATA){

        $input = (string)$input;
        $basedir = "$OJ_DATA/$pid";

        $fp = @fopen ( $basedir . "/$filename", "w" );
        if($fp){
            fputs ( $fp, preg_replace ( "(\r\n)", "\n", $input ) );
            fclose ( $fp );
        }else{
            echo "Error while opening".$basedir . "/$filename ,try [chgrp -R www-data $OJ_DATA] and [chmod -R 771 $OJ_DATA ] ";

        }
    }

    public function image_save_file($filepath ,$base64_encoded_img){

        $fp=fopen($filepath ,"wb");

        fwrite($fp,base64_decode($base64_encoded_img));

        fclose($fp);
    }
}